package com.wmyg.antifake.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.wmyg.antifake.alipay.AlipayConfig;
import com.wmyg.antifake.entity.Order;
import com.wmyg.antifake.entity.Record;
import com.wmyg.antifake.repository.OrderRepository;
import com.wmyg.antifake.repository.RecordRepository;
import com.wmyg.antifake.service.PayNoticeService;
import com.wmyg.antifake.service.RecordService;
import com.wmyg.antifake.wxpay.MiaomarkWxConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author 王卓逸
 * @program TODO
 * @description TODO
 * @create 2019-05-21
 */
@Service
public class PayNoticeServiceImpl implements PayNoticeService {

    @Autowired
    RecordRepository recordRepository;

    @Autowired
    RecordService recordService;

    @Autowired
    OrderRepository orderRepository;

    @Value("${wxpay.usesandbox}")
    Boolean useSandbox;

    @Value(value = "${alipay.usesandbox}")
    Boolean aliuseSandbox;

    private final static String SUCCESS = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

    @Override
    public String wxpayNoticeHandle(String notifyData) {
        try {
            MiaomarkWxConfig miaomarkWxConfig = new MiaomarkWxConfig();
            WXPay wxpay = new WXPay(miaomarkWxConfig, WXPayConstants.SignType.MD5, useSandbox);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);  // 转换成map

            if (useSandbox ? true : wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                // 签名正确
                // 进行处理。
                // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
                if ("CREATECODE".equals(notifyMap.get("attach"))) {
                    Record record = recordRepository.findByWxpayId(notifyMap.get("out_trade_no"));
                    if (record.getPayState() < 4) {
                        record.setPayState(4);
                        recordRepository.save(record);
                        recordService.produceCode(record.getRecordId());
                    }
                } else if ("PRINTORDER".equals(notifyMap.get("attach"))) {
                    Order order = orderRepository.findByWxpayId(notifyMap.get("out_trade_no"));
                    if (order.getOrderState() < 4) {
                        order.setOrderState(4);
                        orderRepository.save(order);
                    }
                }
                return SUCCESS;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String alipayNoticeHandle(Map<String, String> notifyMap) {
        String publicKey = null;
        if (aliuseSandbox) {
            publicKey = AlipayConfig.ALIPAY_PUBLIC_KEY;
        } else {
            publicKey = AlipayConfig.ALIPAY_PUBLIC_KEY_PROD;
        }
        try {
            if (AlipaySignature.rsaCheckV1(notifyMap, publicKey, AlipayConfig.CHARSET, "RSA2")) {
                if ("TRADE_FINISHED".equals(notifyMap.get("trade_status")) || "TRADE_SUCCESS".equals(notifyMap.get("trade_status"))) {
                    if ("C".equals(notifyMap.get("out_trade_no").substring(0, 1))) {
                        Record record = recordRepository.findByAlipayId(notifyMap.get("out_trade_no"));
                        if (record.getPayState() < 4) {
                            record.setPayState(4);
                            recordRepository.save(record);
                            recordService.produceCode(record.getRecordId());
                        }
                    } else if ("P".equals(notifyMap.get("out_trade_no").substring(0, 1))) {
                        Order order = orderRepository.findByWxpayId(notifyMap.get("out_trade_no"));
                        if (order.getOrderState() < 4) {
                            order.setOrderState(4);
                            orderRepository.save(order);
                        }
                    }
                }
                return "success";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "fail";
    }
}
